package com.xxl.job.executor.service.jobhandler;

import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler;
import com.xxl.job.core.handler.annotation.JobHandler;
import com.xxl.job.core.log.XxlJobLogger;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.*;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.net.SocketTimeoutException;
import java.net.URLDecoder;
import java.net.URLEncoder;

/**
 * 跨平台Http任务
 */

@JobHandler(value = "http")
@Component
public class HttpJobHandler extends IJobHandler {
    private static final Logger log = LoggerFactory.getLogger(HttpJobHandler.class);
    private final static int maxTimeout = 86400;//24小时

    @Override
    public ReturnT<String> execute(String param) throws Exception {
        log.info("参数：{}", param);
        // valid
        if (param == null || param.trim().length() == 0) {
            XxlJobLogger.log("param empty");
            return FAIL;
        }
        //初始化参数
        HttpUriRequest request = initParam(param);
        // httpclient
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        try {
            httpClient = HttpClients.createDefault();
            XxlJobLogger.log("正在访问:{}", request.getURI().toString());
            response = httpClient.execute(request);
            String responseMsg = EntityUtils.toString(response.getEntity());
            int statusCode = response.getStatusLine().getStatusCode();
            log.info("返回code：{}", response);
            log.info("返回结果：{}", param);
            if (statusCode != 200) {
                XxlJobLogger.log("返回code：{}", response.getStatusLine().getStatusCode());
                XxlJobLogger.log("返回结果:{}", responseMsg);
                return FAIL;
            }
            XxlJobLogger.log("返回结果:{}", responseMsg);
            return SUCCESS;
        } catch (ConnectTimeoutException e) {
            XxlJobLogger.log("连接超时60秒");
            log.error("连接超时60秒");
            return FAIL;
        } catch (SocketTimeoutException e) {
            XxlJobLogger.log("读取超时");
            log.error("读取超时");
            return FAIL;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            XxlJobLogger.log(e);
            return FAIL;
        } finally {
            if (response != null) {
                response.close();
            }
            if (httpClient != null) {
                httpClient.close();
            }
        }
    }


    private HttpUriRequest initParam(String param) {
        HttpUriRequest request=null;
        String[] split = param.split("@@", 3);
        int length = split.length;
        if (length == 1) {
            HttpGet httpGet = new HttpGet(turnUrl(param));
            httpGet.setConfig(config(maxTimeout));
            request = httpGet;
        } else if (length == 2) {
            String data1 = split[0];
            if (data1.matches("\\d+")) {
                int timeout = Integer.valueOf(data1);
                HttpGet httpGet = new HttpGet(turnUrl(split[1]));
                httpGet.setConfig(config(timeout));
                request = httpGet;
            } else {
                int timeout = maxTimeout;
                request = method(timeout, data1.toUpperCase(), turnUrl(split[1]));
            }
        } else if (length == 3) {
            int timeout = Integer.valueOf(split[1]);
            request = method(timeout, split[0].toUpperCase(), turnUrl(split[2]));
        }
        return request;
    }

    private HttpUriRequest method(int timeout, String method, String url) {
        HttpUriRequest request = null;
        if ("GET".equals(method)) {
            HttpGet httpGet = new HttpGet(url);
            httpGet.setConfig(config(timeout));
            request = httpGet;
        } else if ("POST".equals(method)) {
            HttpPost httpPost = new HttpPost(url);
            httpPost.setConfig(config(timeout));
            request = httpPost;
        } else if ("HEAD".equals(method)) {
            HttpHead httpHead = new HttpHead(url);
            httpHead.setConfig(config(timeout));
            request = httpHead;
        } else if ("PUT".equals(method)) {
            HttpPut httpPut = new HttpPut(url);
            httpPut.setConfig(config(timeout));
            request = httpPut;
        } else if ("OPTIONS".equals(method)) {
            HttpOptions httpOptions = new HttpOptions(url);
            httpOptions.setConfig(config(timeout));
            request = httpOptions;
        } else if ("DELETE".equals(method)) {
            HttpDelete httpDelete = new HttpDelete(url);
            httpDelete.setConfig(config(timeout));
            request = httpDelete;
        } else if ("TRACE".equals(method)) {
            HttpTrace httpTrace = new HttpTrace(url);
            httpTrace.setConfig(config(timeout));
            request = httpTrace;
        } else if ("Patch".equals(method)) {
            HttpPatch httpPatch = new HttpPatch(url);
            httpPatch.setConfig(config(timeout));
            request = httpPatch;
        }
        return request;
    }

    public static void main(String[] args) {
        String url = "http://190.168.0.80:8899/dingDing/sendText?atMobiles=&msgType=1&content=蒙多，想去哪就去哪&";
        String s = new HttpJobHandler().turnUrl(url);
        System.out.println(s);
    }
    //-----------------------------------------------调用示例-----------------------------------------------------
    // post   post@@http://190.168.0.78:8899/dingDing/send/entryInvestigation?timeConfType=1&userId=1
    // get    get@@http://190.168.0.80:8088/update/newOfficial
    // get    http://39.108.208.139:10002/financeTotalFreeze/xxlJobOrderDetail?intervalMonth=-1
    private String turnUrl(String baseUrl) {
        String url = URLDecoder.decode(baseUrl);
        StringBuilder sb = new StringBuilder();
        String[] split = url.split("\\?", 2);
        if (split.length == 2) {
            sb.append(split[0]);
            sb.append("?");
            String param = split[1];
            String[] paramSplit = param.split("&");
            for (int i = 0; i < paramSplit.length; i++) {
                String[] split1 = paramSplit[i].split("=", 2);
                sb.append(split1[0]);
                sb.append("=");
                if (split1.length == 2) sb.append(URLEncoder.encode(split1[1]));
                if (i != paramSplit.length - 1) sb.append("&");
            }
        } else {
            sb.append(url);
        }
        return sb.toString();
    }

    private RequestConfig config(int timeout) {
        return RequestConfig.custom()
                .setConnectTimeout(60 * 1000)    // 设置连接超时时间 60秒钟
                .setSocketTimeout(timeout * 1000)        // 设置读取超时时间
                .setRedirectsEnabled(false)    //禁止重定向
                .build();
    }
}